from machine import Pin, ADC
import time

# ==========================================
# 1. 핀 및 ADC 설정
# ==========================================
# 초록색 LED 게이지 (25%, 50%, 75%, 100%)
led_green = [
    Pin(0, Pin.OUT),  # GP0 - 25%
    Pin(1, Pin.OUT),  # GP1 - 50%
    Pin(2, Pin.OUT),  # GP2 - 75%
    Pin(3, Pin.OUT)   # GP3 - 100%
]

# 잉여 전력 저감용 MOSFET 제어 (GP14)
surplus_mosfet = Pin(14, Pin.OUT)

# 비상 SOS 물리 버튼 (GP13)
btn_sos = Pin(13, Pin.IN, Pin.PULL_UP)

# 비상 SOS 제어 스위치 (GP15)
sos_mosfet = Pin(15, Pin.OUT)

# 실제 전압 감지용 ADC 설정 (GP26 / ADC0)
adc_cap = ADC(Pin(26))

# ==========================================
# 2. 기준 전압 (V) 설정
# ==========================================
ADC_CONVERSION = 3.3 / 65535

TH_25  = 0.75
TH_50  = 1.50
TH_75  = 2.25
TH_100 = 3.00
TH_OFF = 2.85  # 히스테리시스 오프 기준 전압

# ==========================================
# 3. SOS 모스부호 파라미터
# ==========================================
DOT_TIME   = 150
DASH_TIME  = 450
SYMBOL_GAP = 150
CHAR_GAP   = 450
CYCLE_GAP  = 1200

SOS_SEQUENCE = [
    (True, DOT_TIME), (False, SYMBOL_GAP),
    (True, DOT_TIME), (False, SYMBOL_GAP),
    (True, DOT_TIME), (False, CHAR_GAP),
    (True, DASH_TIME), (False, SYMBOL_GAP),
    (True, DASH_TIME), (False, SYMBOL_GAP),
    (True, DASH_TIME), (False, CHAR_GAP),
    (True, DOT_TIME), (False, SYMBOL_GAP),
    (True, DOT_TIME), (False, SYMBOL_GAP),
    (True, DOT_TIME), (False, CYCLE_GAP)
]

# ==========================================
# 4. 상태 관리 변수
# ==========================================
sos_active = False
btn_prev_state = 1
last_btn_time = 0

sos_seq_idx = 0
last_sos_step_time = 0
last_adc_time = 0
surplus_state = False

# 초기 상태 OFF 설정
for led in led_green:
    led.value(0)
surplus_mosfet.value(0)
sos_mosfet.value(0)

print("[Real Sensing Mode] 실제 ADC 전압 측정을 시작합니다...")

# ==========================================
# 5. 메인 루프
# ==========================================
while True:
    current_time = time.ticks_ms()

    # ----------------------------------------------------
    # A. 0.5초(500ms)마다 실제 ADC 전압 측정 및 제어
    # ----------------------------------------------------
    if time.ticks_diff(current_time, last_adc_time) >= 500:
        last_adc_time = current_time
        
        # 실제 ADC 전압 읽기 (노이즈 방지를 위한 5회 평균값 계산)
        raw_val = sum(adc_cap.read_u16() for _ in range(5)) / 5
        v_adc = raw_val * ADC_CONVERSION

        print(f"[ADC Sensing] 현재 측정 전압: {v_adc:.2f} V")

        # 1) 초록색 LED 게이지 제어
        led_green[0].value(1 if v_adc >= TH_25 else 0)
        led_green[1].value(1 if v_adc >= TH_50 else 0)
        led_green[2].value(1 if v_adc >= TH_75 else 0)
        led_green[3].value(1 if v_adc >= TH_100 else 0)

        # 2) 잉여 전력 MOSFET (GP14) 제어 (히스테리시스 적용)
        if v_adc >= TH_100 and not surplus_state:
            surplus_state = True
            surplus_mosfet.value(1)
            print("  --> [GP14 MOSFET ON] 3.0V 이상 도달 (잉여 전력 저감 동작)")
        elif v_adc < TH_OFF and surplus_state:
            surplus_state = False
            surplus_mosfet.value(0)
            print("  --> [GP14 MOSFET OFF] 2.85V 미만 하강 (잉여 전력 저감 중단)")

    # ----------------------------------------------------
    # B. 비상 SOS 버튼 토글 (GP13) - 디바운싱 로직 개선
    # ----------------------------------------------------
    btn_val = btn_sos.value()
    if btn_prev_state == 1 and btn_val == 0:
        if time.ticks_diff(current_time, last_btn_time) > 200:
            sos_active = not sos_active
            last_btn_time = current_time
            
            if not sos_active:
                sos_mosfet.value(0)
            else:
                sos_seq_idx = 0
                last_sos_step_time = current_time
            print(f"[SOS Button Triggered] SOS Active: {sos_active}")
            
    btn_prev_state = btn_val

    # ----------------------------------------------------
    # C. SOS 점멸 제어 (GP15)
    # ----------------------------------------------------
    if sos_active:
        state, duration = SOS_SEQUENCE[sos_seq_idx]
        sos_mosfet.value(1 if state else 0)
        
        if time.ticks_diff(current_time, last_sos_step_time) >= duration:
            last_sos_step_time = current_time
            sos_seq_idx = (sos_seq_idx + 1) % len(SOS_SEQUENCE)
    else:
        sos_mosfet.value(0)

    time.sleep_ms(5)